一.集合
  a.为什么需要集合?
    存储班级中80个同学的成绩?
    第一种方法:使用变量存储,手动定义80个变量存储这个80个同学的成绩,定义非常繁琐
      int student01 = 50;
      int student02 = 70;
      int student03 =100;
      ....
      int student80 = 76;
    第二种方法:使用数组存储
      int[] scores = new int[80];
      scores[0]= 80;
      scores[1]= 90;
       ....
      scores[79]=100;
     后来又来了20个同学,存储这20个同学的成绩?
     由于长度为80的数组,已经存满,我们无法在存储这20个人成绩,要想存储,我们需要在开辟一个长度为100的数组
        int[] newScores=new int[100];
        newScores[0] ~ newScores[79] 存储原来80个人成绩
        newScores[80] ~ newScores[99] 存储新来的20个人的成绩
    第三种方法:
     我们使用别人写的好类来去存储元素,我们不需要在关心空间不够的情况
     我们只需要关心的 元素的存储,元素的取出,元素删除...这一系列操作元素的行为
     那么这个类或者这个类的体系就是集合
  b.集合的通用功能
    1.集合添加,获取功能
        /**
         * 集合体系通用功能:
         * boolean add(Object e)
         *   确保此 collection 包含指定的元素（可选操作）。
         *   向集合中添加元素
         *
         *  int size()
         *           返回此 collection 中的元素数
         *      获取数组的长度,使用length属性,arr.length
         *      获取字符串的长度,使用String类中的length()方法, "abc".length()
         *      获取StringBuilder长度,使用StringBuilder类中的length()方法, new StringBuilder("abc").length();
         *      获取集合中元素的个数,使用集合的size()方法
         *  void clear()
         *           移除此 collection 中的所有元素（可选操作）。
         *            清空集合中的元素
         */
    2.集合的判断功能
        /**
         * 集合的判断功能:
         *    boolean contains(Object o)
         *           判断这个集合中是否包含指定的元素,如果包含返回true
         *           否则返回false
         *           contains方法底层判断元素是否包含在集合中,它其实依赖的是存储元素的boolean equals(Object obj)方法去比较
         *           Person p1 = new Person("无忌", 19);
         *           Person p2 = new Person("敏敏", 18);
         *          c.add(p1);  //p3和p1比较其实就是调用equals方法 相当于 p3.equals(p1),Person类中默认equals()方法比较内存地址值
         *         c.add(p2);//p3和p2比较其实就是调用equals方法 相当于 p3.equals(p2),Person类中默认equals()方法比较内存地址值
         *
         *       Person p3 = new Person("无忌", 19);
         *       System.out.println(c.contains(p3)); //当所有元素都调用equals()方法与p3比较,都返回false,说明这个集合中不存在p3
         *                                            //最终contains方法会false
         *    boolean isEmpty()
         *            判断集合中是否有元素,如果有元素,那么返回false
         *            如果集合中没有元素,那么返回true
         */

    3.集合的删除功能
        /**
         * 集合中的移除功能
         *  boolean remove(Object o)
         *           从集合中移除指定的元素,如果移除成功就返回true,否则返回false
         *           remove()方法依据集合中元素的equals()方法去比较,如果两个元素调用equals()方法返回true,说明存在元素,可以移除,最终remove返回true
         *                     如果集合中所有元素调用equals()与被移除元素比教,都返回false,集合中不存在该元素,移除失败,remove方法返回false
         *          Person p1 = new Person("乔峰", 30);
         *         Person p2 = new Person("阿朱", 20);
         *         c.add(p1);
         *         c.add(p2);
         *
         *         Person p3 = new Person("乔峰", 30);
         *
         *         System.out.println(c.remove(p3));//首先跟p1比较,p1.equals(p3),如果调用Object类中的equals()方法默认比较内存地址值,p1和p3不同,equals()
         *                                        //方法返回false;
         *                                        //在与p2比较 p2.equals(p3),如果调用Object类中的equals()方法默认比较内存地址值,p2和p3不同,equals()
         *                                         //方法返回false;
         *                                          //所有元素都与p3不同,最终remove()返回false
         *       int[] arr={15,19,21};
         *       移除19
         *       移除16
         *
         *    contains()方法与remove()方法底层在判断的时候都是依赖集合中元素的equals()方法
         */
    4.集合的迭代
      a.集合的迭代器相关方法
        /**
         * 集合的通用迭代(遍历)方式:
         *  Iterator iterator()
         *          从集合中获取一个迭代器对象,这个迭代器专门用来遍历集合中的元素
         *
         *  Iterator接口中的方法:
         *    boolean hasNext()
         *       判断集合中是否有遍历的元素,如果有,hasNext()就返回true,如果集合中没有要遍历的元素就返回false
         *    Object next()
         *       取出当前遍历的元素,并返回该元素
         *

         */
      b.并发修改异常
            /**
             * 在使用迭代器遍历集合中容易引发的问题:
             *    需求:定义一个集合,向集合中添加三个字符串:"abc","def","ghk"
             *    当遍历到"ghk"的时候,删除该元素
             * java.util.ConcurrentModificationException:并发修改异常
             *   由于我们在使用迭代器的方法遍历的过程中了,使用了集合的 删除/添加 方法,导致了并发异常
             *   解决:
             *     在使用迭代器遍历的过程中,如果需要增/删元素,使用迭代器的方法来完成,就可以避免这个错误
             *     void remove()
             */
      c.增强for
        /**
         * JDK1.5新特性:
         *   增强for:
         *     用途:一般是用来遍历数组和集合的
         *         要求集合必须继承或实现Iterable接口
         *     格式:
         *       for(要遍历的容器中元素的类型 变量名 : 数组/集合){
         *              //取出元素
         *       }
         *   注意事项:
         *    1.使用增强for遍历集合其实底层使用的依然是迭代器
         *     while(iterator.hashNext()){
         *         iterator.next();
         *     }
         *   2.使用增强for遍历数组的时候,无法操作数组的索引
         *
         */
     5.泛型
       a.类上的泛型
        /**
         * 类上泛型:
         *    格式:
         *       class 类名<E,Q,A,...>{//泛型变量
         *          一旦在类上定义泛型,类中均可以使用定义的泛型变量
         *       }
         *
         *       如果不指定泛型变量的类型,那么这个泛型变量会被替换成Object类型
         */
         当我们创建该类的对象时候,类上的泛型被确定
           类名 引用变量名 = new 类名<指定类型>();
       b.方法上的泛型
        /**
         * 方法上的泛型:
         *    格式:
         *      权限修饰符 <T,Q,E,...> 返回值类型 方法名(T t,Q q,...){ //<T,Q,E,...> 方法上的泛型声明
         *                                                         //可以在方法的形参以及方法内使用
         *
         *      }
         */
        当我们调用该方法传参的时候,方法上的泛型被确定
       c.接口上的泛型
            /**
             * 接口上的泛型
             *   格式:
             *     interface 接口名<T,E,Q...>{//接口上声明的泛型变量,都可以在接口中使用
             *
             *     }
             */
          第一种方式:实现这个接口的时候指定类型,从而确定接口上的泛型
          第二种方式:通过创建实现类对象来指定类型,确定类上的泛型,从而确定接口上的泛型
     6.增强for使用泛型
        Collection<String> c = new ArrayList<String>();
        c.add("abc");
        c.add("bf");
        c.add("ms");
        for (String s : c) {
        System.out.println(s);
        }
      7.泛型优点
        /**
         * 泛型优点
         *   1.使用泛型可以将运行时期可能出现的问题(强制转换异常)提升到编译时期
         *   2.省去强转,可以直接调用集合中元素类型的方法
         */